﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.UI;

namespace Nirvana
{
    [RequireComponent(typeof(RawImage))]
    [AddComponentMenu("Nirvana/UI/Bind/Variable Bind RawImage")]
    public sealed class UIVariableBindRawImage : UIVariableBind
    {

        private static Logger logger = LogSystem.GetLogger("UIVariableBindRawImage");
        [SerializeField]
        [VariableName(UIVariableType.Asset)]
        private string textureBind;

        [SerializeField]
        private bool autoFitNativeSize;

        [SerializeField]
        private bool isSync;

        [SerializeField]
        private bool isRealtimeUnload;

        private RawImage _rawimage;
        private Texture _texture;
        private AssetID assetid;
        private UIVariable _uivariable;
        private bool isOk;

        private  sealed class UIVariableBindRawImageEvent
        {
            internal AssetID _assetid;
            internal UIVariableBindRawImage _rawimage;
            internal void OnLoadComplete(Texture texture)
            {
                if (this._rawimage._rawimage == null)
                {
                    Singleton<TexturePool>.Instance.Free(texture, this._rawimage.isRealtimeUnload);
                    return;
                }
                this._rawimage._texture = texture;
                if (this._rawimage._texture == null)
                {
                    string text = string.Format("Load texture {0} failed.", this._assetid);
                    Debug.LogError(text, this._rawimage.gameObject);
                }
                if (this._rawimage.assetid.Equals(this._assetid))
                {
                    this._rawimage._rawimage.texture = texture;
                    this._rawimage._rawimage.enabled = true;
                    if (this._rawimage.autoFitNativeSize)
                    {
                        this._rawimage._rawimage.SetNativeSize();
                    }
                }
            }
        }
        private  void Awake()
        {
            base.Binds();
            this._rawimage = base.GetComponent<RawImage>();
            this._rawimage.enabled = false;
        }
        private void Update()
        {
            if (this.isOk)
            {
                this.isOk = false;
                AssetID asset = this._uivariable.GetAsset();
                if (!this.assetid.Equals(asset))
                {
                    this.StartLoad(asset);
                }
            }
        }

        protected override void BindVariables()
        {
            Assert.IsNull<UIVariable>(this._uivariable);
            if (!string.IsNullOrEmpty(this.textureBind))
            {
                this._uivariable = base.FindVariable(this.textureBind);
                if (this._uivariable == null)
                {
                    UIVariableBindRawImage.logger.LogWarning("{0} can not find a variable {1}", new object[]
                    {
                        base.name,
                        this.textureBind
                    });
                }
                else
                {
                    this._uivariable.OnValueInitialized += this.OnValueInitialized;
                    this._uivariable.OnValueChanged += this.OnValueInitialized;
                    this._uivariable.Add(this);
                    this.isOk = true;
                }
            }
        }

        protected override void UnbindVariables()
        {
            if (this._uivariable != null)
            {
                this._uivariable.OnValueInitialized -= this.OnValueInitialized;
                this._uivariable.OnValueChanged -= this.OnValueInitialized;
                this._uivariable.Remove(this);
                this._uivariable = null;
            }
            if (this._texture != null)
            {
                if (Application.isPlaying)
                {
                    Singleton<TexturePool>.Instance.Free(this._texture, this.isRealtimeUnload);
                }
                this._texture = null;
            }
        }

        private void OnValueInitialized()
        {
            this.isOk = true;
        }

        private void StartLoad(AssetID assetid)
        {
            if (this.assetid.Equals(assetid))
            {
                return;
            }
            if (this._texture != null)
            {
                if (Application.isPlaying)
                {
                    Singleton<TexturePool>.Instance.Free(this._texture, this.isRealtimeUnload);
                }
                this._texture = null;
            }
            this.assetid = assetid;
            if (assetid.IsEmpty)
            {
                this._rawimage.texture = null;
                return;
            }
            if (Application.isPlaying)
            {
                this.LoadRawImageAsync(assetid);
            }
            else
            {
                this.LoadRawImage(assetid);
            }
        }

        private void LoadRawImageAsync(AssetID assetid)
        {
            UIVariableBindRawImageEvent _event = new UIVariableBindRawImageEvent();
            _event._assetid = assetid;
            _event._rawimage = this;
            Singleton<TexturePool>.Instance.Load(_event._assetid, _event.OnLoadComplete, this.isSync);
        }


        private void LoadRawImage(AssetID assetid)
        {
            UnityEngine.Object obj = assetid.LoadObject<UnityEngine.Object>();
            if (obj != null)
            {
                this._texture = (obj as Texture);
                if (this._texture == null)
                {
                    TextAsset textAsset = obj as TextAsset;
                    if (textAsset != null)
                    {
                        this._texture = this.ConversionImage(textAsset);
                        Resources.UnloadAsset(textAsset);
                    }
                }
            }
            if (this._texture != null)
            {
                this._rawimage.texture = this._texture;
                this._rawimage.enabled = true;
                if (this.autoFitNativeSize)
                {
                    this._rawimage.SetNativeSize();
                }
            }
            else
            {
                this._rawimage.texture = null;
            }
        }


        private Texture2D ConversionImage(TextAsset asset)
        {
            byte[] bytes = asset.bytes;
            TextureFormat textureFormat = TextureFormat.RGB24;

            if (bytes != null && bytes[1] == 80 && bytes[2] == 78 && bytes[3] == 71)
            {
                textureFormat = TextureFormat.RGBA32;

            }
            Texture2D texture2D = new Texture2D(2, 2, textureFormat, false);
            if (!ImageConversion.LoadImage(texture2D, bytes, true))
            {
                return null;
            }
            texture2D.wrapMode = TextureWrapMode.Clamp;
            return texture2D;
        }
    }
}

